using AutoMapper;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web.Mvc;
using ShopPowerTemplate.Entities;
using ShopPowerTemplate.IoC;
using ShopPowerTemplate.Presentation.Mvc.Extensions.ControllerFactories;
using ShopPowerTemplate.Presentation.Mvc.Models;
using ShopPowerTemplate.Presentation.Mvc.ViewModels;

namespace ShopPowerTemplate.Presentation.Mvc.Extensions.BootStrapper
{
    /// <summary>
    /// Default boot strapper implementation
    /// <see cref="ShopPowerTemplate.Presentation.Mvc.Extensions.BootStrapper.IBootStrapper"/>
    /// </summary>
    public partial class DefaultBootStrapper : IBootStrapper
    {
        #region Members

        /// <summary>
        /// Current IoC container
        /// </summary>
        IContainer _CurrentContainer;

        #endregion

        #region Constructors

        /// <summary>
        /// Create a new instance of this boot strapper
        /// </summary>
        /// <param name="container">Default IoC container</param>
        public DefaultBootStrapper(IContainer container)
        {
            if (container == (IContainer)null)
                throw new ArgumentNullException("serviceFactory");

            _CurrentContainer = container;
        }

        #endregion

        #region IBootStrapper Members

        /// <summary>
        /// <see cref="M:ShopPowerTemplate.Presentation.Mvc.Extensions.BootStrapper.IBootStrapper.Boot"/>
        /// </summary>
        public void Boot()
        {
            //Register controllers into MVC infrastructure
            RegisterControllers();

            //register factories
            RegisterFactories();

            //configure automapper mappings
            ConfigureAutoMapper();
        }

        #endregion

        #region Private Methods

        private void RegisterFactories()
        {
            //Create a custom controller factory to resolve controllers with IoC container
            IControllerFactory factory = new IoCControllerFactory(_CurrentContainer);

            //Set new controller factory in ASP.MVC Controller builder
            ControllerBuilder.Current.SetControllerFactory(factory);
        }

        private void RegisterControllers()
        { 
            //In this implementations only controllers in same assembly are registered in IoC container. If you
            // have controllers in a different assembly check this code.

            //Recover excuting assembly.
            Assembly assembly =Assembly.GetExecutingAssembly();

            //Recover all controller types in this assembly.
            IEnumerable<Type> controllers = assembly.GetExportedTypes()
                                                    .Where(x => typeof(IController).IsAssignableFrom(x));

            //Register all controllers types
            foreach (Type item in controllers)
                _CurrentContainer.RegisterType(item);
        }

        private void ConfigureAutoMapper()
        {
			Mapper.CreateMap<Address, CreateAddressViewModel>()
				  .ForMember(m => m.CustomerList, opt => opt.Ignore())
				  .ForMember(m => m.CustomerId, map=>map.MapFrom(e=>e.Customer != null ? (int?)e.Customer.Id: (int?)null));
            Mapper.CreateMap<CreateAddressViewModel, Address>()
				  .ForMember(m => m.Customer, map=>map.MapFrom(e=>e.CustomerId !=null ? new Customer() { Id = e.CustomerId.Value } : (Customer)null));
            Mapper.CreateMap<Address, EditAddressViewModel>()
				  .ForMember(m => m.CustomerList, opt => opt.Ignore())
				  .ForMember(m => m.CustomerId, map=>map.MapFrom(e=>e.Customer != null ? (int?)e.Customer.Id: (int?)null));
            Mapper.CreateMap<EditAddressViewModel, Address>()
				  .ForMember(m => m.Customer, map=>map.MapFrom(e=>e.CustomerId !=null ? new Customer() { Id = e.CustomerId.Value } : (Customer)null));
			Mapper.CreateMap<Address, DetailsAddressViewModel>()
				  .ForMember(m => m.CustomerList, opt => opt.Ignore());
			Mapper.CreateMap<Address, PopUpAddressViewModel>()
				  .ForMember(m => m.CustomerList, opt => opt.Ignore())
				  .ForMember(m => m.CustomerId, map=>map.MapFrom(e=>e.Customer != null ? (int?)e.Customer.Id: (int?)null));
            Mapper.CreateMap<PopUpAddressViewModel, Address>()
				  .ForMember(m => m.Customer, map=>map.MapFrom(e=>e.CustomerId !=null ? new Customer() { Id = e.CustomerId.Value } : (Customer)null));
			Mapper.CreateMap<AppSettings, CreateAppSettingsViewModel>();
            Mapper.CreateMap<CreateAppSettingsViewModel, AppSettings>();
            Mapper.CreateMap<AppSettings, EditAppSettingsViewModel>();
            Mapper.CreateMap<EditAppSettingsViewModel, AppSettings>();
			Mapper.CreateMap<AppSettings, DetailsAppSettingsViewModel>();
			Mapper.CreateMap<AppSettings, PopUpAppSettingsViewModel>();
            Mapper.CreateMap<PopUpAppSettingsViewModel, AppSettings>();
			Mapper.CreateMap<Category, CreateCategoryViewModel>();
            Mapper.CreateMap<CreateCategoryViewModel, Category>()
				  .ForMember(m => m.Subcategories, opt => opt.Ignore())
				  .ForMember(m => m.Image, opt => opt.Ignore());
            Mapper.CreateMap<Category, EditCategoryViewModel>()
				  .ForMember(m => m.HasImage, map=>map.MapFrom(e=>e.Image != null))
				  .ForMember(m => m.ImageIsImage, map=>map.MapFrom(e=> Helpers.FileHelper.IsImage(e.Image)));
            Mapper.CreateMap<EditCategoryViewModel, Category>()
				  .ForMember(m => m.Subcategories, opt => opt.Ignore())
				  .ForMember(m => m.Image, opt => opt.Ignore());
			Mapper.CreateMap<Category, DetailsCategoryViewModel>()
				  .ForMember(m => m.HasImage, map=>map.MapFrom(e=>e.Image != null))
				  .ForMember(m => m.ImageIsImage, map=>map.MapFrom(e=> Helpers.FileHelper.IsImage(e.Image)));
			Mapper.CreateMap<Category, PopUpCategoryViewModel>();
            Mapper.CreateMap<PopUpCategoryViewModel, Category>()
				  .ForMember(m => m.Subcategories, opt => opt.Ignore())
				  .ForMember(m => m.Image, opt => opt.Ignore());
			Mapper.CreateMap<Customer, CreateCustomerViewModel>();
            Mapper.CreateMap<CreateCustomerViewModel, Customer>()
				  .ForMember(m => m.Reviews, opt => opt.Ignore())
				  .ForMember(m => m.Orders, opt => opt.Ignore())
				  .ForMember(m => m.Addresses, opt => opt.Ignore());
            Mapper.CreateMap<Customer, EditCustomerViewModel>();
            Mapper.CreateMap<EditCustomerViewModel, Customer>()
				  .ForMember(m => m.Reviews, opt => opt.Ignore())
				  .ForMember(m => m.Orders, opt => opt.Ignore())
				  .ForMember(m => m.Addresses, opt => opt.Ignore());
			Mapper.CreateMap<Customer, DetailsCustomerViewModel>();
			Mapper.CreateMap<Customer, PopUpCustomerViewModel>();
            Mapper.CreateMap<PopUpCustomerViewModel, Customer>()
				  .ForMember(m => m.Reviews, opt => opt.Ignore())
				  .ForMember(m => m.Orders, opt => opt.Ignore())
				  .ForMember(m => m.Addresses, opt => opt.Ignore());
			Mapper.CreateMap<Image, CreateImageViewModel>()
				  .ForMember(m => m.ProductList, opt => opt.Ignore())
				  .ForMember(m => m.ProductId, map=>map.MapFrom(e=>e.Product != null ? (int?)e.Product.Id: (int?)null));
            Mapper.CreateMap<CreateImageViewModel, Image>()
				  .ForMember(m => m.Data, opt => opt.Ignore())
				  .ForMember(m => m.Product, map=>map.MapFrom(e=>e.ProductId !=null ? new Product() { Id = e.ProductId.Value } : (Product)null));
            Mapper.CreateMap<Image, EditImageViewModel>()
				  .ForMember(m => m.ProductList, opt => opt.Ignore())
				  .ForMember(m => m.ProductId, map=>map.MapFrom(e=>e.Product != null ? (int?)e.Product.Id: (int?)null))
				  .ForMember(m => m.HasData, map=>map.MapFrom(e=>e.Data != null))
				  .ForMember(m => m.DataIsImage, map=>map.MapFrom(e=> Helpers.FileHelper.IsImage(e.Data)));
            Mapper.CreateMap<EditImageViewModel, Image>()
				  .ForMember(m => m.Data, opt => opt.Ignore())
				  .ForMember(m => m.Product, map=>map.MapFrom(e=>e.ProductId !=null ? new Product() { Id = e.ProductId.Value } : (Product)null));
			Mapper.CreateMap<Image, DetailsImageViewModel>()
				  .ForMember(m => m.ProductList, opt => opt.Ignore())
				  .ForMember(m => m.HasData, map=>map.MapFrom(e=>e.Data != null))
				  .ForMember(m => m.DataIsImage, map=>map.MapFrom(e=> Helpers.FileHelper.IsImage(e.Data)));
			Mapper.CreateMap<Image, PopUpImageViewModel>()
				  .ForMember(m => m.ProductList, opt => opt.Ignore())
				  .ForMember(m => m.ProductId, map=>map.MapFrom(e=>e.Product != null ? (int?)e.Product.Id: (int?)null));
            Mapper.CreateMap<PopUpImageViewModel, Image>()
				  .ForMember(m => m.Data, opt => opt.Ignore())
				  .ForMember(m => m.Product, map=>map.MapFrom(e=>e.ProductId !=null ? new Product() { Id = e.ProductId.Value } : (Product)null));
			Mapper.CreateMap<Option, CreateOptionViewModel>()
				  .ForMember(m => m.OptionTypeList, opt => opt.Ignore())
				  .ForMember(m => m.OptionTypeId, map=>map.MapFrom(e=>e.OptionType != null ? (int?)e.OptionType.Id: (int?)null));
            Mapper.CreateMap<CreateOptionViewModel, Option>()
				  .ForMember(m => m.ProductDetails, opt => opt.Ignore())
				  .ForMember(m => m.OptionType, map=>map.MapFrom(e=>e.OptionTypeId !=null ? new OptionType() { Id = e.OptionTypeId.Value } : (OptionType)null));
            Mapper.CreateMap<Option, EditOptionViewModel>()
				  .ForMember(m => m.OptionTypeList, opt => opt.Ignore())
				  .ForMember(m => m.OptionTypeId, map=>map.MapFrom(e=>e.OptionType != null ? (int?)e.OptionType.Id: (int?)null));
            Mapper.CreateMap<EditOptionViewModel, Option>()
				  .ForMember(m => m.ProductDetails, opt => opt.Ignore())
				  .ForMember(m => m.OptionType, map=>map.MapFrom(e=>e.OptionTypeId !=null ? new OptionType() { Id = e.OptionTypeId.Value } : (OptionType)null));
			Mapper.CreateMap<Option, DetailsOptionViewModel>()
				  .ForMember(m => m.OptionTypeList, opt => opt.Ignore());
			Mapper.CreateMap<Option, PopUpOptionViewModel>()
				  .ForMember(m => m.OptionTypeList, opt => opt.Ignore())
				  .ForMember(m => m.OptionTypeId, map=>map.MapFrom(e=>e.OptionType != null ? (int?)e.OptionType.Id: (int?)null));
            Mapper.CreateMap<PopUpOptionViewModel, Option>()
				  .ForMember(m => m.ProductDetails, opt => opt.Ignore())
				  .ForMember(m => m.OptionType, map=>map.MapFrom(e=>e.OptionTypeId !=null ? new OptionType() { Id = e.OptionTypeId.Value } : (OptionType)null));
			Mapper.CreateMap<OptionType, CreateOptionTypeViewModel>();
            Mapper.CreateMap<CreateOptionTypeViewModel, OptionType>()
				  .ForMember(m => m.Options, opt => opt.Ignore());
            Mapper.CreateMap<OptionType, EditOptionTypeViewModel>();
            Mapper.CreateMap<EditOptionTypeViewModel, OptionType>()
				  .ForMember(m => m.Options, opt => opt.Ignore());
			Mapper.CreateMap<OptionType, DetailsOptionTypeViewModel>();
			Mapper.CreateMap<OptionType, PopUpOptionTypeViewModel>();
            Mapper.CreateMap<PopUpOptionTypeViewModel, OptionType>()
				  .ForMember(m => m.Options, opt => opt.Ignore());
			Mapper.CreateMap<Order, CreateOrderViewModel>()
				  .ForMember(m => m.CustomerList, opt => opt.Ignore())
				  .ForMember(m => m.OrderStateList, opt => opt.Ignore())
				  .ForMember(m => m.CustomerId, map=>map.MapFrom(e=>e.Customer != null ? (int?)e.Customer.Id: (int?)null))
				  .ForMember(m => m.OrderStateId, map=>map.MapFrom(e=>e.OrderState != null ? (int?)e.OrderState.Id: (int?)null));
            Mapper.CreateMap<CreateOrderViewModel, Order>()
				  .ForMember(m => m.OrderDetails, opt => opt.Ignore())
				  .ForMember(m => m.Customer, map=>map.MapFrom(e=>e.CustomerId !=null ? new Customer() { Id = e.CustomerId.Value } : (Customer)null))
				  .ForMember(m => m.OrderState, map=>map.MapFrom(e=>e.OrderStateId !=null ? new OrderState() { Id = e.OrderStateId.Value } : (OrderState)null));
            Mapper.CreateMap<Order, EditOrderViewModel>()
				  .ForMember(m => m.CustomerList, opt => opt.Ignore())
				  .ForMember(m => m.OrderStateList, opt => opt.Ignore())
				  .ForMember(m => m.CustomerId, map=>map.MapFrom(e=>e.Customer != null ? (int?)e.Customer.Id: (int?)null))
				  .ForMember(m => m.OrderStateId, map=>map.MapFrom(e=>e.OrderState != null ? (int?)e.OrderState.Id: (int?)null));
            Mapper.CreateMap<EditOrderViewModel, Order>()
				  .ForMember(m => m.OrderDetails, opt => opt.Ignore())
				  .ForMember(m => m.Customer, map=>map.MapFrom(e=>e.CustomerId !=null ? new Customer() { Id = e.CustomerId.Value } : (Customer)null))
				  .ForMember(m => m.OrderState, map=>map.MapFrom(e=>e.OrderStateId !=null ? new OrderState() { Id = e.OrderStateId.Value } : (OrderState)null));
			Mapper.CreateMap<Order, DetailsOrderViewModel>()
				  .ForMember(m => m.CustomerList, opt => opt.Ignore())
				  .ForMember(m => m.OrderStateList, opt => opt.Ignore());
			Mapper.CreateMap<Order, PopUpOrderViewModel>()
				  .ForMember(m => m.CustomerList, opt => opt.Ignore())
				  .ForMember(m => m.OrderStateList, opt => opt.Ignore())
				  .ForMember(m => m.CustomerId, map=>map.MapFrom(e=>e.Customer != null ? (int?)e.Customer.Id: (int?)null))
				  .ForMember(m => m.OrderStateId, map=>map.MapFrom(e=>e.OrderState != null ? (int?)e.OrderState.Id: (int?)null));
            Mapper.CreateMap<PopUpOrderViewModel, Order>()
				  .ForMember(m => m.OrderDetails, opt => opt.Ignore())
				  .ForMember(m => m.Customer, map=>map.MapFrom(e=>e.CustomerId !=null ? new Customer() { Id = e.CustomerId.Value } : (Customer)null))
				  .ForMember(m => m.OrderState, map=>map.MapFrom(e=>e.OrderStateId !=null ? new OrderState() { Id = e.OrderStateId.Value } : (OrderState)null));
			Mapper.CreateMap<OrderDetail, CreateOrderDetailViewModel>()
				  .ForMember(m => m.OrderList, opt => opt.Ignore())
				  .ForMember(m => m.ProductDetailList, opt => opt.Ignore())
				  .ForMember(m => m.OrderId, map=>map.MapFrom(e=>e.Order != null ? (int?)e.Order.Id: (int?)null))
				  .ForMember(m => m.ProductDetailId, map=>map.MapFrom(e=>e.ProductDetail != null ? (int?)e.ProductDetail.Id: (int?)null));
            Mapper.CreateMap<CreateOrderDetailViewModel, OrderDetail>()
				  .ForMember(m => m.Order, map=>map.MapFrom(e=>e.OrderId !=null ? new Order() { Id = e.OrderId.Value } : (Order)null))
				  .ForMember(m => m.ProductDetail, map=>map.MapFrom(e=>e.ProductDetailId !=null ? new ProductDetail() { Id = e.ProductDetailId.Value } : (ProductDetail)null));
            Mapper.CreateMap<OrderDetail, EditOrderDetailViewModel>()
				  .ForMember(m => m.OrderList, opt => opt.Ignore())
				  .ForMember(m => m.ProductDetailList, opt => opt.Ignore())
				  .ForMember(m => m.OrderId, map=>map.MapFrom(e=>e.Order != null ? (int?)e.Order.Id: (int?)null))
				  .ForMember(m => m.ProductDetailId, map=>map.MapFrom(e=>e.ProductDetail != null ? (int?)e.ProductDetail.Id: (int?)null));
            Mapper.CreateMap<EditOrderDetailViewModel, OrderDetail>()
				  .ForMember(m => m.Order, map=>map.MapFrom(e=>e.OrderId !=null ? new Order() { Id = e.OrderId.Value } : (Order)null))
				  .ForMember(m => m.ProductDetail, map=>map.MapFrom(e=>e.ProductDetailId !=null ? new ProductDetail() { Id = e.ProductDetailId.Value } : (ProductDetail)null));
			Mapper.CreateMap<OrderDetail, DetailsOrderDetailViewModel>()
				  .ForMember(m => m.OrderList, opt => opt.Ignore())
				  .ForMember(m => m.ProductDetailList, opt => opt.Ignore());
			Mapper.CreateMap<OrderDetail, PopUpOrderDetailViewModel>()
				  .ForMember(m => m.OrderList, opt => opt.Ignore())
				  .ForMember(m => m.ProductDetailList, opt => opt.Ignore())
				  .ForMember(m => m.OrderId, map=>map.MapFrom(e=>e.Order != null ? (int?)e.Order.Id: (int?)null))
				  .ForMember(m => m.ProductDetailId, map=>map.MapFrom(e=>e.ProductDetail != null ? (int?)e.ProductDetail.Id: (int?)null));
            Mapper.CreateMap<PopUpOrderDetailViewModel, OrderDetail>()
				  .ForMember(m => m.Order, map=>map.MapFrom(e=>e.OrderId !=null ? new Order() { Id = e.OrderId.Value } : (Order)null))
				  .ForMember(m => m.ProductDetail, map=>map.MapFrom(e=>e.ProductDetailId !=null ? new ProductDetail() { Id = e.ProductDetailId.Value } : (ProductDetail)null));
			Mapper.CreateMap<OrderState, CreateOrderStateViewModel>();
            Mapper.CreateMap<CreateOrderStateViewModel, OrderState>()
				  .ForMember(m => m.Orders, opt => opt.Ignore());
            Mapper.CreateMap<OrderState, EditOrderStateViewModel>();
            Mapper.CreateMap<EditOrderStateViewModel, OrderState>()
				  .ForMember(m => m.Orders, opt => opt.Ignore());
			Mapper.CreateMap<OrderState, DetailsOrderStateViewModel>();
			Mapper.CreateMap<OrderState, PopUpOrderStateViewModel>();
            Mapper.CreateMap<PopUpOrderStateViewModel, OrderState>()
				  .ForMember(m => m.Orders, opt => opt.Ignore());
			Mapper.CreateMap<Product, CreateProductViewModel>()
				  .ForMember(m => m.SubcategoryList, opt => opt.Ignore())
				  .ForMember(m => m.SubcategoryId, map=>map.MapFrom(e=>e.Subcategory != null ? (int?)e.Subcategory.Id: (int?)null));
            Mapper.CreateMap<CreateProductViewModel, Product>()
				  .ForMember(m => m.Images, opt => opt.Ignore())
				  .ForMember(m => m.Reviews, opt => opt.Ignore())
				  .ForMember(m => m.ProductDetails, opt => opt.Ignore())
				  .ForMember(m => m.Subcategory, map=>map.MapFrom(e=>e.SubcategoryId !=null ? new Subcategory() { Id = e.SubcategoryId.Value } : (Subcategory)null));
            Mapper.CreateMap<Product, EditProductViewModel>()
				  .ForMember(m => m.SubcategoryList, opt => opt.Ignore())
				  .ForMember(m => m.SubcategoryId, map=>map.MapFrom(e=>e.Subcategory != null ? (int?)e.Subcategory.Id: (int?)null));
            Mapper.CreateMap<EditProductViewModel, Product>()
				  .ForMember(m => m.Images, opt => opt.Ignore())
				  .ForMember(m => m.Reviews, opt => opt.Ignore())
				  .ForMember(m => m.ProductDetails, opt => opt.Ignore())
				  .ForMember(m => m.Subcategory, map=>map.MapFrom(e=>e.SubcategoryId !=null ? new Subcategory() { Id = e.SubcategoryId.Value } : (Subcategory)null));
			Mapper.CreateMap<Product, DetailsProductViewModel>()
				  .ForMember(m => m.SubcategoryList, opt => opt.Ignore());
			Mapper.CreateMap<Product, PopUpProductViewModel>()
				  .ForMember(m => m.SubcategoryList, opt => opt.Ignore())
				  .ForMember(m => m.SubcategoryId, map=>map.MapFrom(e=>e.Subcategory != null ? (int?)e.Subcategory.Id: (int?)null));
            Mapper.CreateMap<PopUpProductViewModel, Product>()
				  .ForMember(m => m.Images, opt => opt.Ignore())
				  .ForMember(m => m.Reviews, opt => opt.Ignore())
				  .ForMember(m => m.ProductDetails, opt => opt.Ignore())
				  .ForMember(m => m.Subcategory, map=>map.MapFrom(e=>e.SubcategoryId !=null ? new Subcategory() { Id = e.SubcategoryId.Value } : (Subcategory)null));
			Mapper.CreateMap<ProductDetail, CreateProductDetailViewModel>()
				  .ForMember(m => m.ProductList, opt => opt.Ignore())
				  .ForMember(m => m.ProductId, map=>map.MapFrom(e=>e.Product != null ? (int?)e.Product.Id: (int?)null));
            Mapper.CreateMap<CreateProductDetailViewModel, ProductDetail>()
				  .ForMember(m => m.OrderDetails, opt => opt.Ignore())
				  .ForMember(m => m.Option, opt => opt.Ignore())
				  .ForMember(m => m.Product, map=>map.MapFrom(e=>e.ProductId !=null ? new Product() { Id = e.ProductId.Value } : (Product)null));
            Mapper.CreateMap<ProductDetail, EditProductDetailViewModel>()
				  .ForMember(m => m.ProductList, opt => opt.Ignore())
				  .ForMember(m => m.ProductId, map=>map.MapFrom(e=>e.Product != null ? (int?)e.Product.Id: (int?)null));
            Mapper.CreateMap<EditProductDetailViewModel, ProductDetail>()
				  .ForMember(m => m.OrderDetails, opt => opt.Ignore())
				  .ForMember(m => m.Option, opt => opt.Ignore())
				  .ForMember(m => m.Product, map=>map.MapFrom(e=>e.ProductId !=null ? new Product() { Id = e.ProductId.Value } : (Product)null));
			Mapper.CreateMap<ProductDetail, DetailsProductDetailViewModel>()
				  .ForMember(m => m.ProductList, opt => opt.Ignore());
			Mapper.CreateMap<ProductDetail, PopUpProductDetailViewModel>()
				  .ForMember(m => m.ProductList, opt => opt.Ignore())
				  .ForMember(m => m.ProductId, map=>map.MapFrom(e=>e.Product != null ? (int?)e.Product.Id: (int?)null));
            Mapper.CreateMap<PopUpProductDetailViewModel, ProductDetail>()
				  .ForMember(m => m.OrderDetails, opt => opt.Ignore())
				  .ForMember(m => m.Option, opt => opt.Ignore())
				  .ForMember(m => m.Product, map=>map.MapFrom(e=>e.ProductId !=null ? new Product() { Id = e.ProductId.Value } : (Product)null));
			Mapper.CreateMap<Review, CreateReviewViewModel>()
				  .ForMember(m => m.CustomerList, opt => opt.Ignore())
				  .ForMember(m => m.ProductList, opt => opt.Ignore())
				  .ForMember(m => m.CustomerId, map=>map.MapFrom(e=>e.Customer != null ? (int?)e.Customer.Id: (int?)null))
				  .ForMember(m => m.ProductId, map=>map.MapFrom(e=>e.Product != null ? (int?)e.Product.Id: (int?)null));
            Mapper.CreateMap<CreateReviewViewModel, Review>()
				  .ForMember(m => m.Customer, map=>map.MapFrom(e=>e.CustomerId !=null ? new Customer() { Id = e.CustomerId.Value } : (Customer)null))
				  .ForMember(m => m.Product, map=>map.MapFrom(e=>e.ProductId !=null ? new Product() { Id = e.ProductId.Value } : (Product)null));
            Mapper.CreateMap<Review, EditReviewViewModel>()
				  .ForMember(m => m.CustomerList, opt => opt.Ignore())
				  .ForMember(m => m.ProductList, opt => opt.Ignore())
				  .ForMember(m => m.CustomerId, map=>map.MapFrom(e=>e.Customer != null ? (int?)e.Customer.Id: (int?)null))
				  .ForMember(m => m.ProductId, map=>map.MapFrom(e=>e.Product != null ? (int?)e.Product.Id: (int?)null));
            Mapper.CreateMap<EditReviewViewModel, Review>()
				  .ForMember(m => m.Customer, map=>map.MapFrom(e=>e.CustomerId !=null ? new Customer() { Id = e.CustomerId.Value } : (Customer)null))
				  .ForMember(m => m.Product, map=>map.MapFrom(e=>e.ProductId !=null ? new Product() { Id = e.ProductId.Value } : (Product)null));
			Mapper.CreateMap<Review, DetailsReviewViewModel>()
				  .ForMember(m => m.CustomerList, opt => opt.Ignore())
				  .ForMember(m => m.ProductList, opt => opt.Ignore());
			Mapper.CreateMap<Review, PopUpReviewViewModel>()
				  .ForMember(m => m.CustomerList, opt => opt.Ignore())
				  .ForMember(m => m.ProductList, opt => opt.Ignore())
				  .ForMember(m => m.CustomerId, map=>map.MapFrom(e=>e.Customer != null ? (int?)e.Customer.Id: (int?)null))
				  .ForMember(m => m.ProductId, map=>map.MapFrom(e=>e.Product != null ? (int?)e.Product.Id: (int?)null));
            Mapper.CreateMap<PopUpReviewViewModel, Review>()
				  .ForMember(m => m.Customer, map=>map.MapFrom(e=>e.CustomerId !=null ? new Customer() { Id = e.CustomerId.Value } : (Customer)null))
				  .ForMember(m => m.Product, map=>map.MapFrom(e=>e.ProductId !=null ? new Product() { Id = e.ProductId.Value } : (Product)null));
			Mapper.CreateMap<ShippingCost, CreateShippingCostViewModel>();
            Mapper.CreateMap<CreateShippingCostViewModel, ShippingCost>();
            Mapper.CreateMap<ShippingCost, EditShippingCostViewModel>();
            Mapper.CreateMap<EditShippingCostViewModel, ShippingCost>();
			Mapper.CreateMap<ShippingCost, DetailsShippingCostViewModel>();
			Mapper.CreateMap<ShippingCost, PopUpShippingCostViewModel>();
            Mapper.CreateMap<PopUpShippingCostViewModel, ShippingCost>();
			Mapper.CreateMap<Subcategory, CreateSubcategoryViewModel>()
				  .ForMember(m => m.CategoryList, opt => opt.Ignore())
				  .ForMember(m => m.CategoryId, map=>map.MapFrom(e=>e.Category != null ? (int?)e.Category.Id: (int?)null));
            Mapper.CreateMap<CreateSubcategoryViewModel, Subcategory>()
				  .ForMember(m => m.Products, opt => opt.Ignore())
				  .ForMember(m => m.Category, map=>map.MapFrom(e=>e.CategoryId !=null ? new Category() { Id = e.CategoryId.Value } : (Category)null));
            Mapper.CreateMap<Subcategory, EditSubcategoryViewModel>()
				  .ForMember(m => m.CategoryList, opt => opt.Ignore())
				  .ForMember(m => m.CategoryId, map=>map.MapFrom(e=>e.Category != null ? (int?)e.Category.Id: (int?)null));
            Mapper.CreateMap<EditSubcategoryViewModel, Subcategory>()
				  .ForMember(m => m.Products, opt => opt.Ignore())
				  .ForMember(m => m.Category, map=>map.MapFrom(e=>e.CategoryId !=null ? new Category() { Id = e.CategoryId.Value } : (Category)null));
			Mapper.CreateMap<Subcategory, DetailsSubcategoryViewModel>()
				  .ForMember(m => m.CategoryList, opt => opt.Ignore());
			Mapper.CreateMap<Subcategory, PopUpSubcategoryViewModel>()
				  .ForMember(m => m.CategoryList, opt => opt.Ignore())
				  .ForMember(m => m.CategoryId, map=>map.MapFrom(e=>e.Category != null ? (int?)e.Category.Id: (int?)null));
            Mapper.CreateMap<PopUpSubcategoryViewModel, Subcategory>()
				  .ForMember(m => m.Products, opt => opt.Ignore())
				  .ForMember(m => m.Category, map=>map.MapFrom(e=>e.CategoryId !=null ? new Category() { Id = e.CategoryId.Value } : (Category)null));
			Mapper.CreateMap<User, CreateUserViewModel>();
            Mapper.CreateMap<CreateUserViewModel, User>();
            Mapper.CreateMap<User, EditUserViewModel>();
            Mapper.CreateMap<EditUserViewModel, User>();
			Mapper.CreateMap<User, DetailsUserViewModel>();
			Mapper.CreateMap<User, PopUpUserViewModel>();
            Mapper.CreateMap<PopUpUserViewModel, User>();
            Mapper.AssertConfigurationIsValid(); //Validate mappings
        }

        #endregion 
    }
}
